#pragma once

#ifndef __CR_PLATFORM_MACROS_H__
#define __CR_PLATFORM_MACROS_H__

/**
*	CHUANGRUN FOUNDATION KIT (crfk)
*	Design by blutter@163.com
*	2018/05/27
*/

#ifdef __cplusplus
/* NAMESPACE */ 
#define NS_CR_BEGIN	namespace crfk {
#define NS_CR_END	}
#define USING_NS_CR	using namespace crfk
#define NS_CR	::crfk::
#else
#define NS_CR_BEGIN 
#define NS_CR_END 
#define USING_NS_CR 
#define NS_CR
#endif 

//#define  CC_STATIC
#if defined(_WIN32)
	#if defined(CC_STATIC)
	#	define CR_DLL
	#else
	#	if defined(_USRDLL)
	#		define CR_DLL     __declspec(dllexport)
	#	else         /* use a DLL library */
	#		define CR_DLL     __declspec(dllimport)
	#	endif
	#endif
#else
	#	define CR_DLL
#endif

#ifdef _WIN32
	#define CRNO_RETURN_HINT() do {} while (false)
	#define CR_CRASH() __debugbreak()

	#include <tchar.h>
#else
	#define CRNO_RETURN_HINT() do {} while (false)
	#define CR_CRASH() do { CRNO_RETURN_HINT(); *(int *)(uintptr_t)0xbbadbeef = 0; } while (false)
	#define __T(x)		(x)	
	#define _T(x)       __T(x)
	#ifndef _STD
	#	define _STD ::std:: 
	#	define _STD_BEGIN namespace std {
	# 	define _STD_END }
	#endif
#endif // _WIN32



#ifndef CR_ALWAYSBREAK
#  ifdef _DEBUG
#    define CR_ALWAYSBREAK(cond) do { \
              if (cond) break; \
              CRNO_RETURN_HINT(); \
              crDebugf("%s:%d: failed assertion \"%s\"\n", __FILE__, __LINE__, #cond); \
              CR_CRASH(); \
        } while (false)
#  else
#    define CR_ALWAYSBREAK(cond) do { if (cond) break; SK_CRASH(); } while (false)
#  endif
#endif

#if defined(_DEBUG)
	#define INLINE	
	#define CR_ASSERT(cond)              CR_ALWAYSBREAK(cond)
#else
	#define INLINE inline
	#define CR_ASSERT(cond) 
#endif

#ifndef _STD_FWD
#define _STD_FWD(...) _STD forward<decltype(__VA_ARGS__)>(__VA_ARGS__)
#endif // !_STD_FWD

#if _HAS_CXX17
namespace fs = std::filesystem;
#else	
#if !(defined _MSC_VER) || _MSC_VER > 1800 
namespace fs = std::experimental::filesystem::v1;
#else 
namespace fs = std::tr2::sys;
#endif
#endif

#if !(defined _MSC_VER) || _MSC_VER > 1800
#define NOEXCEPT		noexcept
#define NOEXCEPTX		noexcept
#define NOEXCEPT_OP		noexcept
#else
#define NOEXCEPT		_NOEXCEPT
#define NOEXCEPTX
#define NOEXCEPT_OP(x) 
#endif

extern "C" void CR_DLL crDebugf(const char format[], ...);
 
#endif /*__CR_PLATFORM_MACROS_H__*/

